/**
  ******************************************************************************
  * @文件名           : dri_slaver_wiip_rtu.c
  * @作者             : citunhk
  * @功能介绍         : 从机驱动
  *	@日期             : 2024.3.21
  ******************************************************************************
  * @注意
  *
  * 本文件中不应调用上层文件
  *
  ******************************************************************************
  *更改记录
  *日期 修改人 修改内容
  *
  *
  *
  ******************************************************************************
  */
#include "dri_slaver_wiip_rtu.h"
#include "dri_slaver.h"
#include "bsp_usart.h"
#include "fml_crc.h"
#include "sys_data.h"
#include "dri_flash_sst.h"

/**
* @函数名	DRI_WIIP_RTU_TxRegSlaverValue
* @功能	    将03指令需要的数据填充到相应的寄存器中
* @入口参数	无
* @返回值	无
*/
void DRI_WIIP_RTU_TxRegSlaverValue(unsigned int uiRegIndex)
{
	uint16_t pModbusSlaverUpData = 0;
	switch(uiRegIndex)
	{
	case 1:
		pModbusSlaverUpData = rSlaver_State_Control1;  //控制字1
		break;

	case 11:
		pModbusSlaverUpData = rSlaver_State_Chiller1;  //状态字1
		break;

	case 21:
		pModbusSlaverUpData = rSlaver_State_Alarm1;  //报警字1
		break;
	case 22:
		pModbusSlaverUpData = rSlaver_State_Alarm2;  //报警字2
		break;

	case 31:
		pModbusSlaverUpData=((int16_t)(100*UP.Para.SV_Temp1));//主温度设定值
		break;
	case 32:
		pModbusSlaverUpData = 100*UP.Para.SV_Flow;  //流量设定值
		break;
	case 33:
		pModbusSlaverUpData = 10*UP.Para.SV_Press;  //压力设定值
		break;

	case 71:
		pModbusSlaverUpData = ((int16_t)(100*gPV_TempAbmi));  //环境温度实测值
		break;

	case 91:
		pModbusSlaverUpData = ((int16_t)(100*gPV_Temp1));//主温度实测值
		break;
	case 92:
		pModbusSlaverUpData = 10*gPV_Press_Out;//出液压力实测值
		break;
	case 93:
		pModbusSlaverUpData = ((int16_t)(100*gPV_Temp2));//辅温度实测值
		break;
	case 94:
		pModbusSlaverUpData = 10*gPV_Press_In;//回液压力实测值
		break;
	case 95:
		pModbusSlaverUpData = 100*gPV_Flow;//流量实测值
		break;
	case 96:
		pModbusSlaverUpData = 100*gPV_DI;//水质实测值
		break;
		default:
//			gSlaver_State = 50;
		break;
	}

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = (uint8_t)(pModbusSlaverUpData >> 8);
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = (uint8_t)(pModbusSlaverUpData & 0x00ff);
}

/**
* @函数名	DRI_WIIP_RTU_ProcessModbusSlaverUpCmd03
* @功能	    03指令解析处理
* @入口参数	无
* @返回值	无
*/
void DRI_WIIP_RTU_ProcessModbusSlaverUpCmd03(void)
{
	uint16_t uiStart;
	uint16_t uiQuantity;
	uint16_t uiEnd;
	uint16_t i;

	//字节个数
	uiQuantity = ((uint16_t)gBus485_Slaver_RxBuffer[4] << 8) + gBus485_Slaver_RxBuffer[5];
	if(uiQuantity > 0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	//起始地址
	uiStart = ((uint16_t)gBus485_Slaver_RxBuffer[2] << 8) + gBus485_Slaver_RxBuffer[3] + 1;
	//结束地址
	uiEnd = uiStart + uiQuantity;
//		if(ModbusUpListenOnly)
//		{
//			ModbusUpUartInit();
//			return;
//		}
	pBus485_Slaver_TxCounter = 0;
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[0];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[1];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = uiQuantity * 2;
	for(i = uiStart; i < uiEnd; i++)
	{
		DRI_WIIP_RTU_TxRegSlaverValue(i);
	}
	DRI_MakeModbusSlaverUpMsgCrc();
	DRI_SlaverUpStartTx();
}

/**
* @函数名	DRI_WIIP_RTU_ProcessModbusSlaverUpCmd06
* @功能	    06指令解析处理
* @入口参数	无
* @返回值	无
*/
//写单个寄存器指令
void DRI_WIIP_RTU_ProcessModbusSlaverUpCmd06()
{
	uint16_t uiStart;
	uint16_t uiQuantity=0;
	uint8_t pFlag_Save = 1;  //保存标志位

	if(uiQuantity>0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	uiStart=((uint16_t)gBus485_Slaver_RxBuffer[2]<<8)+gBus485_Slaver_RxBuffer[3]+1;
//	if(ModbusUpListenOnly)
//	{
//		ModbusUpUartInit();
//		return;
//	}
	pBus485_Slaver_TxCounter=0;
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[0];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[1];

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[2];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[3];

	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[4];
	pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++]=gBus485_Slaver_RxBuffer[5];
	DRI_MakeModbusSlaverUpMsgCrc();
	DRI_SlaverUpStartTx();

	if(uiStart >= 0)
	{
		switch(uiStart)
		{
		case 1:
			rSlaver_State_Control1 = (gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5];//控制字1
			break;

		case 31:
			UP.Para.SV_Temp1 = ((float)(int16_t)((gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5]))/100;//主温度设定
			break;
		case 32:
			UP.Para.SV_Flow = ((gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5])/100;//流量设定值
			break;
		case 33:
			UP.Para.SV_Press = ((gBus485_Slaver_RxBuffer[4]<<8) + gBus485_Slaver_RxBuffer[5])/10;//压力设定值
			break;
			default:
//				gSlaver_State = 50;
				break;
		}

		if(pFlag_Save == 1)
		{
			DRI_Flash_Erase_4KByte(ADDR_USER_PARA);//写入前擦除
			DRI_Flash_AAI_WriteBuffer(&UP.flashBuff[0], ADDR_USER_PARA, 500);//写入用户初值到buff中
		}
	}
}

/**
* @函数名	DRI_WIIP_RTU_ProcessModbusSlaverUpCmd16
* @功能	    16指令解析处理
* @入口参数	无
* @返回值	无
*/
//写多个寄存器指令  16指令
void DRI_WIIP_RTU_ProcessModbusSlaverUpCmd16()
{
	uint16_t uiStart;
	uint16_t uiEnd;
	uint16_t uiQuantity;
	uint16_t i;
	uint16_t FlagCmdModbus = 0;
	uint8_t pFlag_Save = 1;  //保存标志位

	//寄存器个数
	uiQuantity=((uint16_t)gBus485_Slaver_RxBuffer[4]<<8)+gBus485_Slaver_RxBuffer[5];
	if(uiQuantity>0x7D)
	{
		//ExceptionResponse(0x03);
		return;
	}
	//寄存器起始地址
	uiStart=((uint16_t)gBus485_Slaver_RxBuffer[2]<<8)+gBus485_Slaver_RxBuffer[3]+1;
	//结束地址
	uiEnd=uiStart+uiQuantity;
	for(i=uiStart;i<uiEnd;i++)
	{
		 switch(i)
		 {
			case 1:  //控制字1
				rSlaver_State_Control1 = ((uint16_t)((gBus485_Slaver_RxBuffer[7]<<8) + gBus485_Slaver_RxBuffer[8]));
				FlagCmdModbus = FlagCmdModbus + 2;
				break;

			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 30:
				FlagCmdModbus = FlagCmdModbus + 2;
				break;

			case 31:  //主温度设定值
				UP.Para.SV_Temp1 = ((float)(int16_t)((gBus485_Slaver_RxBuffer[7+FlagCmdModbus]<<8) + gBus485_Slaver_RxBuffer[8+FlagCmdModbus]))/100;
				FlagCmdModbus = FlagCmdModbus + 2;
				break;
			case 32:  //流量设定值
				UP.Para.SV_Flow = (((uint16_t)(gBus485_Slaver_RxBuffer[7+FlagCmdModbus]<<8) + gBus485_Slaver_RxBuffer[8+FlagCmdModbus])/100);
				FlagCmdModbus = FlagCmdModbus + 2;
				break;
			case 33:  //压力设定值
				UP.Para.SV_Press = (((uint16_t)(gBus485_Slaver_RxBuffer[7+FlagCmdModbus]<<8) + gBus485_Slaver_RxBuffer[8+FlagCmdModbus])/10);
				FlagCmdModbus = FlagCmdModbus + 2;
				break;
			default:
//				gSlaver_State = 50;
				break;
		}
	}

//    if(FlagCmdModbus==1)
//    {
    	FlagCmdModbus = 0;
		pBus485_Slaver_TxCounter = 0;
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[0];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[1];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[2];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[3];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[4];
		pBus485_Slaver_TxBuffer[pBus485_Slaver_TxCounter++] = gBus485_Slaver_RxBuffer[5];
		DRI_MakeModbusSlaverUpMsgCrc();
		DRI_SlaverUpStartTx();
//    }

		if(pFlag_Save == 1)
		{
			DRI_Flash_Erase_4KByte(ADDR_USER_PARA);//写入前擦除
			DRI_Flash_AAI_WriteBuffer(&UP.flashBuff[0], ADDR_USER_PARA, 500);//写入用户初值到buff中
		}
}

/**
* @函数名	Task_Slaver_RX_Integration
* @功能	    RS485从机数据处理
* @入口参数	无
* @返回值	无
*/
void DRI_WIIP_RTU_Slaver_RX_Integration(void)
{
	uint16_t puiCRCResult;
	uint8_t pModbusUpFrameSlaverStatus = 1;
	if(gBus485_Slaver_RxCounter < 3) //如果数据字节少于3
	{
		pModbusUpFrameSlaverStatus = 1;
	}
	else
	{
		uint16_t crcdata;
//		Crc16Arg.pCrc16ArgsPuchMsg = gBus485_Slaver_RxBuffer;  //获取等待CRC数组地址
//		Crc16Arg.crc16ArgsPuchMsgLen = gBus485_Slaver_RxCounter - 2;  //获取等待CRC数组长度  不包含原CRC
		puiCRCResult = Crc16(gBus485_Slaver_RxBuffer, gBus485_Slaver_RxCounter - 2);
//		puiCRCResult = Crc16Arg.returnValue;  //得到CRC数值
		crcdata = (gBus485_Slaver_RxBuffer[gBus485_Slaver_RxCounter - 1] << 8)|(gBus485_Slaver_RxBuffer[gBus485_Slaver_RxCounter - 2]);
		gBus485_Slaver_RxCounter = 0;  //清除计数标志
		if((crcdata - puiCRCResult) == 0)//CRC校验通过
		{
			if((gBus485_Slaver_RxBuffer[0] == UP.Para.RS485_Addr) || (gBus485_Slaver_RxBuffer[0] == 0))
			{
				pModbusUpFrameSlaverStatus=0;  //接收成功
			}
		}
		else
		{
			pModbusUpFrameSlaverStatus=1;//接收失败
		}
	}
	if(pModbusUpFrameSlaverStatus==0)
	{
		if(gBus485_Slaver_RxBuffer[0])  //地址不为0
		{
			switch(gBus485_Slaver_RxBuffer[1])  //判断指令
			{
				case 3://读多个寄存器
					gSlaver_State = 0;
					DRI_WIIP_RTU_ProcessModbusSlaverUpCmd03();
					break;
				case 6://写单个寄存器
					gSlaver_State = 0;
					DRI_WIIP_RTU_ProcessModbusSlaverUpCmd06();
					break;
				case 16://写多个寄存器
					gSlaver_State = 0;
					DRI_WIIP_RTU_ProcessModbusSlaverUpCmd16();
					break;
				default:
				break;
			}
		}
	}
}








